home *** CD-ROM | disk | FTP | other *** search
- /////////////////////////////////////////////////////////////////////////////
- // //
- // TUTPROG10.CPP - VGA Trainer Program 10 (in Turbo C++ 3.0) //
- // //
- // "The VGA Trainer Program" was originally written by Denthor of //
- // Asphyxia. It contained some nice pascal source and documentation. But //
- // then Snowman came along. He saw disorder, he saw inefficiency, he //
- // saw PASCAL. Denthor couldn't stop Snowman, so Snowman went on to //
- // convert tha pascal source to C++. ...and the people were happy. //
- // //
- // Program Notes : This program presents the basics of Chain-4. //
- // //
- // Just for reference, this is the command line I use: //
- // //
- // tcc -mc -a -G -2 -O tut10.cpp //
- // //
- // The way things are set up, there is no need to compile //
- // or link tut10.cpp and gfx2.cpp seperately. //
- // //
- // Author : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za //
- // Translator : Christopher G. Mann - r3cgm@dax.cc.uakron.edu //
- // //
- // Last Modified : February 1, 1995 //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- // //
- // INCLUDE FILES //
- // //
-
- #include <conio.h>
- // clrscr(), getch(), kbhit()
- #include <iostream.h>
- // cout
- #include <stdlib.h>
- // rand()
- #include "gfx2.cpp"
- // SetText(), WaitRetrace(), Pal::
-
- // //
- // TYPEDEFS //
- // //
-
- // unsigned chars are sissy
- typedef unsigned char byte;
- typedef unsigned int word;
-
- // //
- // CONSTANTS //
- // //
-
- const byte BIT[897] = {
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33,2,151,5,149,6,148,7,147,8,49,2,
- 95,8,49,4,93,9,49,3,93,4,2,3,49,4,92,4,3,3,48,4,92,4,3,4,48,4,91,4,4,
- 3,48,4,92,4,3,4,48,3,58,2,32,4,4,4,47,4,57,3,31,4,5,3,48,3,57,4,30,4,
- 5,4,47,3,57,5,29,4,6,4,46,4,57,4,29,4,7,3,47,3,58,2,30,4,7,4,46,4,90,
- 4,7,4,46,3,90,4,8,4,27,2,16,3,90,4,8,9,22,3,16,3,89,4,5,13,8,6,8,3,15,
- 3,90,4,2,15,6,10,6,3,16,3,6,1,21,1,9,2,7,1,21,6,14,18,9,5,2,4,5,4,1,4,
- 10,3,4,5,10,2,7,3,8,2,5,3,9,3,7,8,13,13,1,4,9,4,5,3,5,3,1,6,9,3,3,6,9,
- 4,5,4,8,3,3,4,9,3,6,9,11,10,6,4,8,4,6,3,4,11,8,3,2,7,9,5,4,4,9,3,2,4,
- 9,3,6,4,4,2,8,10,9,4,7,4,6,3,5,5,3,3,8,3,1,8,8,5,4,5,8,3,3,3,9,4,5,4,
- 5,2,5,10,12,4,7,3,5,5,4,5,4,3,7,3,1,4,1,3,9,4,5,4,9,3,2,3,10,3,6,3,5,
- 3,4,10,13,3,8,3,2,7,5,4,5,3,7,7,1,3,9,4,5,5,9,3,1,3,10,3,6,3,5,4,4,5,
- 1,4,12,4,8,3,2,5,6,4,5,4,6,6,2,4,8,4,5,5,10,6,10,4,5,4,5,3,5,2,3,4,13,
- 4,8,3,3,1,9,3,6,3,7,5,3,3,5,1,3,3,5,5,4,2,5,5,11,3,6,3,5,4,10,3,14,4,
- 8,3,12,3,6,4,6,5,3,3,5,2,2,4,4,6,4,2,5,5,6,1,3,4,5,3,6,3,10,4,14,4,5,
- 1,2,4,11,3,6,3,7,5,3,3,4,3,1,4,4,6,4,3,5,4,6,2,3,3,6,3,5,4,9,4,15,3,5,
- 2,3,4,9,3,6,4,7,4,3,3,5,2,2,3,4,7,3,3,6,3,6,3,2,4,5,4,5,3,10,3,15,4,4,
- 3,4,3,9,3,6,3,7,4,4,3,4,3,1,4,3,3,1,3,3,3,6,4,6,2,3,3,6,3,5,4,9,4,15,
- 4,4,3,4,4,7,3,6,4,7,4,3,3,4,3,2,3,3,3,2,3,2,4,5,5,5,3,2,4,6,3,5,4,8,4,
- 16,4,4,2,6,3,7,3,5,4,7,4,4,3,3,3,3,8,2,3,2,4,5,6,4,3,3,3,7,3,4,5,8,4,
- 16,4,4,2,6,3,6,3,5,4,8,3,5,8,3,9,2,3,1,4,6,6,3,3,4,3,7,3,3,6,7,4,17,4,
- 4,3,5,3,6,3,4,4,9,3,5,8,3,7,3,8,6,3,1,4,1,4,3,4,7,3,2,3,1,3,7,4,17,4,
- 4,3,5,3,5,11,9,3,6,7,4,6,4,7,6,3,2,8,4,3,8,7,2,3,6,4,18,3,5,4,3,4,5,
- 10,10,3,6,6,6,4,4,6,7,3,4,6,5,3,8,7,2,4,4,4,19,3,5,10,5,3,1,6,11,3,7,
- 3,16,5,7,4,4,5,6,3,8,6,3,5,3,4,19,3,6,9,5,3,18,2,25,5,9,3,6,3,7,2,10,
- 3,6,4,3,3,20,3,8,5,6,3,44,6,10,2,39,3,3,2,22,2,19,3,43,7,101,3,42,8,
- 102,3,41,4,1,4,101,4,39,5,2,3,102,3,39,4,4,3,102,3,38,4,4,4,101,3,38,
- 4,5,3,102,3,37,4,5,4,101,4,36,4,6,3,102,3,37,3,6,4,102,3,36,4,6,3,102,
- 3,37,3,6,3,103,3,37,3,5,4,102,4,37,3,4,4,103,3,38,10,104,3,38,9,105,2,
- 40,7,106,2,41,4,0};
-
- // //
- // FUNCTION PROTOTYPES //
- // //
-
- void InitChain4();
- void C4PutPixel(word X, word Y, byte Col);
- void Plane (byte Which);
- void MoveTo (word X, word Y);
- void Putpic (int x, int y);
- void Play ();
-
- // //
- // GLOBAL VARIABLES //
- // //
-
- // Just for fun, change this to "const byte SIZE = 80" and try to run
- // the program. It is generally a good programming practice to use
- // contant variables when you know that the values should not change.
- // However, this program uses lots of assembler. I guess that a constant
- // byte is stored differently than just a normal byte. Go figure! :)
-
- byte SIZE = 80; // Size = 40 = 1 across, 4 down
- // Size = 80 = 2 across, 2 down
- // Size = 160 = 4 across, 1 down
-
-
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // MAIN FUNCTION //
- // //
- ///////////////////////////////////////////////////////////////////////////////
-
- void main() {
-
- clrscr();
- cout
- << "Hello there! Here is the tenth tutorial, on Chain-4! You will notice\n"
- << "that there are two files here : one contains all of our graphics\n"
- << "based routines, and one is the demo program.\n\n"
- << "In the demo program, we will do the necessary port stuff to get into\n"
- << "Chain-4. Once in Chain-4 mode, I will put down text saying ASPHYXIA\n"
- << "over the entire screen. After a key is pressed, the viewport will\n"
- << "bounce around, displaying the entire Chain-4 screen. The program will\n"
- << "end when [ESC] is pressed. The code here is really basic (except for\n"
- << "those port values), and should be very easy to understand.\n\n";
-
- cout
- << "Yo, Snowman here. Frankly I'm tired of just converting these\n"
- << "bloody tutorials! :) I am going to start doing some ""creative""\n"
- << "things in these programs. The first deviant thing I'm doing is\n"
- << "flipping Denthor's snazzy logo so that <Asphyxia> is reversed.\n"
- << "Hey, we all got to break out and have fun sometime, right? :)\n\n";
- cout << "Hit any key to continue ...";
- getch();
-
- InitChain4();
- Play();
-
- SetText();
- cout
- << "All done. This concludes the tenth sample program in the ASPHYXIA\n"
- << "Training series. You may reach DENTHOR under the names of GRANT\n"
- << "SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n"
- << "Connectix BBS user, and occasionally read RSAProg. E-mail me at :\n"
- << " smith9@batis.bis.und.ac.za\n"
- << "The numbers are available in the main text. You may also write to me at:\n"
- << " Grant Smith\n"
- << " P.O. Box 270\n"
- << " Kloof\n"
- << " 3640\n"
- << " Natal\n"
- << " South Africa\n"
- << "I hope to hear from you soon!\n\n";
- cout << "Hit any key to exit ...";
- getch();
-
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // InitChain4() - This function gets you into Chain 4 mode. //
- // Note: As soon as I find documentation, this function //
- // will be better documented. - Snowman //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- void InitChain4() {
-
- asm {
- mov ax, 0x13 // routine 13 = MCGA mode
- int 0x10 // do it!
- mov dx, 0x3C4 // Port 0x3C4 = Sequencer Address Register
- mov al, 4 // Index 4 = memory mode
- out dx, al // send it
- inc dx // Port 0x3C5 ... here we set the mem mode
- in al, dx
- and al, not 0x08
- or al, 0x04
- out dx, al
- mov dx, 0x3CE
- mov al, 5
- out dx, al
- inc dx
- in al, dx
- and al, not 0x10
- out dx, al
- dec dx
- mov al, 6
- out dx, al
- inc dx
- in al, dx
- and al, not 0x02
- out dx, al
- mov dx, 0x3C4
- mov ax, (0x0F shl 8) + 2
- out dx, ax
- mov ax, 0xA000
- mov es, ax
- sub di, di
- mov ax, 0x0000 // 0x8080
- mov cx, 32768
- cld
- rep stosw // Clear garbage off the screen ...
-
- mov dx, 0x3D4
- mov al, 0x14
- out dx, al
- inc dx
- in al, dx
- and al, not 0x40
- out dx, al
- dec dx
- mov al, 0x17
- out dx, al
- inc dx
- in al, dx
- or al, 0x40
- out dx, al
-
- mov dx, 0x3D4
- mov al, 0x13
- out dx, al
- inc dx
- mov al, [SIZE] // Size * 8 = Pixels across. Only 320 are visible
- out dx, al
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // C4PutPixel() - This puts a pixel on the chain 4 screen. //
- // Note: As soon as I find documentation, this function //
- // will be better documented. - Snowman //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- void C4PutPixel(word X, word Y, byte Col) {
-
- asm {
- mov ax,[Y]
- xor bx,bx
- mov bl,[SIZE]
- imul bx
- shl ax,1
- mov bx,ax
- mov ax, [X]
- mov cx, ax
- shr ax, 2
- add bx, ax
- and cx, 00000011b
- mov ah, 1
- shl ah, cl
- mov dx, 0x3C4 // Sequencer Register
- mov al, 2 // Map Mask Index
- out dx, ax
- mov ax, 0xA000
- mov es, ax
- mov al, [Col]
- mov es: [bx], al
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // Plane() - This sets the plane to write to in Chain 4. //
- // Note: As soon as I find documentation, this function //
- // will be better documented. - Snowman //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- void Plane (byte Which) {
-
- asm {
- mov al, 0x2
- mov ah, 1
- mov cl, [Which]
- shl ah, cl
- mov dx, 0x3C4 // Sequencer Register
- out dx, ax
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // MoveTo() - This moves to position X*4 on a chain 4 screen. //
- // Note: As soon as I find documentation, this function //
- // will be better documented. - Snowman //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- void MoveTo (word X, word Y) {
-
- word O = Y*SIZE*2+X;
-
- asm {
- mov bx, [O]
- mov ah, bh
- mov al, 0x0C
-
- mov dx, 0x3D4
- out dx, ax
-
- mov ah, bl
- mov al, 0x0D
- mov dx, 0x3D4
- out dx, ax
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // Putpic() - This puts the picture at coordinates x,y on the chain-4 //
- // screen. //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- void Putpic (int x, int y) {
-
- int loop1, loop2, cur=0;
- word depth = 1;
-
- // for every element of the picture data...
- for (loop1=0; loop1<897; loop1++) {
- for (loop2=0; loop2<BIT[loop1]; loop2++) {
- // read the tut10.txt file for more information on what this does
- if (cur != 0)
- // take out the "155-" to make the logo face the right direction
- C4PutPixel(155-(depth % 155)+x, (depth / 155)+y,(depth / 155));
- depth++;
- }
- cur = (cur+1) % 2;
- }
- }
-
-
- /////////////////////////////////////////////////////////////////////////////
- // //
- // Play() - The function that does it all... //
- // //
- /////////////////////////////////////////////////////////////////////////////
-
- void Play() {
-
- int loop1, loop2, xpos, ypos, xdir, ydir;
- Pal PicPal[64];
- char ch = 1;
-
- // This sets up the pallette for the picture
- for (loop1=1; loop1<63; loop1++) {
- PicPal[loop1].PalSet(loop1,0,62-loop1);
- PicPal[loop1].PalPut(loop1);
- }
-
- // This moves the view to the top left hand corner
- MoveTo(0,0);
-
- // This places the picture all over the chain-4 screen
- for (loop1=0; loop1<4; loop1++)
- for (loop2=0; loop2<6; loop2++)
- Putpic(loop1*160, loop2*66);
- getch();
-
- // Random start positions/movements for the view
- xpos = (rand() % 78) + 1;
- ypos = (rand() % 198) + 1;
- xdir = 1;
- ydir = 1;
-
- // Main loop (move around the Chain-4 Screen)
- do {
- if (kbhit()) ch = getch();
- MoveTo(xpos, ypos);
- // Take this out and watch the screen go crazy!
- WaitRetrace();
- xpos += xdir;
- ypos += ydir;
- // Hit a boundry, change direction
- if ((xpos > 79) || (xpos < 1)) xdir *= -1;
- if ((ypos > 199) || (ypos < 1)) ydir *= -1;
- if (ch == 0) ch = getch();
- } while (ch != 27); // if the escape code was 27 (escape key) then exit
-
- }
-